<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>fabric</title>
		<script src="https://picture.52hrttpic.com/cdn/js/fabric.min.js"></script>
		<style type="text/css">
			* {
				margin: 0;
				padding: 0;
			}

			ul {
				display: flex;
				list-style: none;
			}

			ul li {
				width: 50px;
				height: 30px;
				line-height: 30px;
				border: 1px solid #000;
				margin-right: 20px;
				text-align: center;
			}
		</style>
	</head>
	<body>
		<canvas id="canvas" width="500" height="500"></canvas>

		<ul class="bottom">
			<li class="back">
				<p>撤销</p>
			</li>
			<li class="restore">
				<p>恢复</p>
			</li>
			<li class="write">
				<p>手写</p>
			</li>
			<li class="characters">
				<p>文字</p>
			</li>
			<li class="rights">
				<p>打钩</p>
			</li>
			<li class="error">
				<p>打叉</p>
			</li>
			<li class="rotate">
				<p>旋转</p>
			</li>
			<li class="save">
				<p>保存</p>
			</li>
			<li class="test">
				<p>测试</p>
			</li>
			<!-- <li @click="zoomIn">
		        <p>放大</p>
		      </li>
		      <li @click="zoomOut"><p>缩小</p></li> -->
		</ul>
		
	</body>

  <script>
    // 未完成 正在开发中。。
class myFabric {
    delList = []; // 被删除的数据
    isDrawingMode = false; // 是否开启自由绘画
    canvas = null; // 主体
    backgroundColor = ''; // 背景颜色
    brushWidth = 1; // 笔刷大小
    brushColor = '#000000'; // 笔刷颜色
    eraserBrushWidth = 0; // 橡皮擦笔刷大小
    fontSize = 0; // 字体大小
    constructor(config) {
        this.backgroundColor = config.backgroundColor ? config.backgroundColor : '#ffffff'
        this.canvas = new fabric.Canvas(config.id, {
            backgroundColor: this.backgroundColor,
            width: config.width,
            height: config.height
            //backgroundVpt: false // 不受视口变换影响（也就是不管拖拽还是缩放画布，背景图都不受影响）
        })
        myCanvas = this.canvas
    }
    // 销毁实例
    destroy() {
        let el = this.canvas.getElement()
        this.canvas.dispose()
        el.remove()
    }
    // 是否开启自由绘画
    DrawingMode(bool) {
        this.isDrawingMode = bool
        this.canvas.isDrawingMode = bool
        // 不允许超过边界
        this.canvas.freeDrawingBrush.limitedToCanvasSize = true
    }
    // 修改笔刷大小
    setBrushSize(size) {
        this.brushWidth = size
        this.canvas.isDrawingMode = true
        this.canvas.freeDrawingBrush.width = size;
    }
    // 修改画笔颜色
    setBrushColor(color) {
        this.brushColor = color
        this.canvas.isDrawingMode = true
        this.canvas.freeDrawingBrush.color = color;
    }
    // 添加橡皮擦
    addEraser() {
        this.canvas.isDrawingMode = true // 进入绘画模式
        this.canvas.freeDrawingBrush = new fabric.EraserBrush(this.canvas) // 使用橡皮擦画笔
        this.canvas.freeDrawingBrush.width = this.eraserBrushWidth // 设置画笔粗细为 10
    }
    // 修改橡皮擦笔刷大小
    setEraserSize(size) {
        this.eraserBrushWidth = size
        this.canvas.isDrawingMode = true
        this.canvas.freeDrawingBrush.width = size;
    }
    // 取消橡皮擦
    cancelEraser() {
        this.canvas.isDrawingMode = false // 进入绘画模式
        this.canvas.freeDrawingBrush = new fabric.PencilBrush(this.canvas) // 使用画笔画笔
        this.canvas.freeDrawingBrush.width = 1 // 设置画笔粗细为 10
    }
    // 清除画布
    clear() {
        this.canvas.clear();
        this.canvas.backgroundColor = this.backgroundColor
    }

    // 自定义控件
    addControl(ele) {
        // 创建自定义控件并添加到矩形里
        ele.controls.deleteControl = new fabric.Control({
            x: 0.5,
            y: -0.5,
            offsetY: -16,
            offsetX: 16,
            cursorStyle: 'pointer', // 鼠标移到控件时的指针样式
            mouseUpHandler: (eventData, transform)=> {
                let target = transform.target
                let canvas = target.canvas
                canvas.remove(target) // 删除元素
                canvas.requestRenderAll() // 刷新画布
            }, // 鼠标抬起时触发的事件
            render: function (ctx, left, top, styleOverride, fabricObject) { // 渲染一个粉红色的正方形
                ctx.save()
                let size = this.cornerSize
                ctx.fillStyle = 'pink'
                ctx.translate(left, top)
                ctx.fillRect(-size / 2, -size / 2, size, size)
                ctx.restore()
            },
            cornerSize: 24
        })
    }
    // 添加文字
    addText(color) {
        // 创建Text元素
        const itext = new fabric.IText('', {
            top: 60, // 文本到画布顶部的距离
            left: 100, // 文本到画布左侧的距离
            splitByGrapheme: true, // 自动换行
            fill: color,// 文字颜色
        })
        this.canvas.add(itext).setActiveObject(itext)
        itext.enterEditing()
        this.addControl(itext)
    }
    // 修改文字大小
    setTextSize(size) {
        this.fontSize = size
        let activeTxt = this.canvas.getActiveObject()
        if (!activeTxt) return
        if (activeTxt.isEditing) {
            // 编辑状态
            activeTxt.setSelectionStyles({ 'fontSize': size })
        } else {
            activeTxt.fontSize = size
            let s = activeTxt.styles
            // 遍历行和列
            for (let i in s) {
                for (let j in s[i]) {
                    s[i][j].fontSize = size // 针对每个字设置字号
                }
            }
            activeTxt.dirty = true
        }
        this.canvas.renderAll()
    }
    // 修改文字颜色
    setTextColor(color) {
        this.fontColor = color
        let activeTxt = this.canvas.getActiveObject()
        if (!activeTxt) return
        if (activeTxt.isEditing) {
            // 编辑状态
            activeTxt.setSelectionStyles({ 'fill': color })
        } else {
            activeTxt.fill = color
            let s = activeTxt.styles
            // 遍历行和列
            for (let i in s) {
                for (let j in s[i]) {
                    s[i][j].fill = color // 针对每个字设置字号
                }
            }
            activeTxt.dirty = true
        }
        this.canvas.renderAll()
    }
    // 添加图片 url 接收的是base64
    addImg(url) {
        fabric.Image.fromURL(
            url, // 图片路径
            img => {
                img.top = 100,
                    img.left = 300,
                    this.canvas.add(img) // 将图片插入到画布中
                    this.addControl(img)
            }
        )
    }
    // 保存
    save() {
       return this.canvas.toDataURL();
    }
    // 撤销
    back() {
        if (this.canvas._objects.length > 0) {
            this.delList.push(this.canvas._objects.pop());
            this.canvas.renderAll();
        }
    }
    // 恢复
    restore() {
        if (this.delList.length > 0) {
            this.isRedoing = true;
            this.canvas.add(this.delList.pop());
            this.canvas.renderAll();
        }
    }

    test() {
        console.log(this.canvas);
    }
    // 创建一个用于读取图片的 Promise 函数
    getBase64FromImageUrl(url) {
        return new Promise((resolve, reject) => {
            const img = new Image();
            img.crossOrigin = 'anonymous';
            img.onload = () => {
                const canvas = document.createElement('canvas');
                canvas.width = img.width;
                canvas.height = img.height;
                const ctx = canvas.getContext('2d');
                ctx.drawImage(img, 0, 0);
                let dataURL
                if (url.indexOf('jpg') > -1 || url.indexOf('jpeg') > -1) {
                    dataURL = canvas.toDataURL('image/jpeg');
                } else if (url.indexOf('png') > -1) {
                    dataURL = canvas.toDataURL('image/png');
                }
                resolve(dataURL);
            };
            img.onerror = reject;
            img.src = url;
        });
    }
}

  </script>
  <script>
    
		  const myCanvas = new myFabric({	
				id: 'canvas',
				url: 'http://1251481829.vod2.myqcloud.com/48804df0vodtransgzp1251481829/8eeca8613270835010470728685/sampleSnapshot/sampleSnapshot_10_1.jpg'
			})
      console.log(myCanvas)
            // 恢复
			let restore = document.querySelector('.restore')
			// 撤销
			let back = document.querySelector('.back')
			// 文字
			let characters = document.querySelector('.characters')
			// 手写
			let write = document.querySelector('.write')
			// 打勾
			let right = document.querySelector('.rights')
			// 打叉
			let error = document.querySelector('.error')
			// 旋转
			let rotate = document.querySelector('.rotate')
			// 保存
			let save = document.querySelector('.save')
			// 测试
			let test = document.querySelector('.test')
			// 自由绘画
			write.onclick = function(){
        console.log('myCanvas', myCanvas)
				myCanvas.DrawingMode()
			}
			// 文字
			characters.onclick = function(){
				myCanvas.addText()
			}
			// 打勾
			right.onclick = function(){
				myCanvas.addImg('right')
			}
			// 打叉
			error.onclick = function(){
				myCanvas.addImg('error')
			}
			// 旋转
			rotate.onclick = function(){
				myCanvas.rotate(90)
			}
			// 保存
			save.onclick = function(){
				myCanvas.save(90)
			}
			// 恢复
			restore.onclick = function(){
				myCanvas.restore()
			}
			// 撤销
			back.onclick = function(){
				myCanvas.back()
			}
			// 测试
			test.onclick = function(){
				myCanvas.test()
			}
		</script>
</html>
